package com.chenjj.java.test.httpclient;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.protocol.HttpClientContext;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.LaxRedirectStrategy;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;

/**
 * 自动重定向
 * 参考：
 * 重定向问题：https://blog.csdn.net/z69183787/article/details/104314558
 * CAS单点登录介绍以及通过JAVA后台模拟单点登录：https://juejin.cn/post/7146504478311743496#heading-26
 * Java httpclient实现CAS单点登录：https://blog.csdn.net/cyony/article/details/82759394
 *
 */
public class CasAuthUtil {
    private static String doCasLoginRequest(HttpClient httpclient, String url) throws IOException {
        try {
            String result = "";
            HttpGet httpget = new HttpGet(url);
            HttpResponse response = httpclient.execute(httpget);
            HttpEntity entity = response.getEntity();
            BufferedReader rd = new BufferedReader(new InputStreamReader(entity.getContent(), "UTF-8"));
            String tempLine = rd.readLine();
            String s = "<input type=\"hidden\" name=\"lt\" value=\"";
            while (tempLine != null) {
                int index = tempLine.indexOf(s);
                if (index != -1) {
                    String s1 = tempLine.substring(index + s.length());
                    int index1 = s1.indexOf("\"");
                    if (index1 != -1)
                        result = s1.substring(0, index1);
                }
                tempLine = rd.readLine();
            }
            if (entity != null) {
                entity.getContent().close();
            }
            return result;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    public static CloseableHttpClient casLogin(String url) throws Exception {

        //DefaultHttpClient httpClient = new SSLClient();

        //ssl httpclient
        RequestConfig config = RequestConfig.custom().setConnectTimeout(50000)
                .setConnectionRequestTimeout(10000).setSocketTimeout(50000)
                .setCircularRedirectsAllowed(true)
                .setRedirectsEnabled(true).build();
        HttpClientBuilder builder = HttpClientBuilder.create();
        builder.setRedirectStrategy(new LaxRedirectStrategy());
        builder.setDefaultRequestConfig(config);
        CloseableHttpClient httpClient = wrapSslClient(builder);
        HttpClientContext context = HttpClientContext.create();

        HttpPost post = new HttpPost(url);
        post.setHeader("User-Agent","Mozilla");
        List<NameValuePair> nvps = new ArrayList<NameValuePair>();
        nvps.add(new BasicNameValuePair("username", "flinkoper"));
        nvps.add(new BasicNameValuePair("password", "Sunline@123"));
        nvps.add(new BasicNameValuePair("lt", doCasLoginRequest(httpClient, url)));
        nvps.add(new BasicNameValuePair("_eventId", "submit"));
        nvps.add(new BasicNameValuePair("geolocation", ""));
        nvps.add(new BasicNameValuePair("submit", "登录"));
        post.setEntity(new UrlEncodedFormEntity(nvps, "UTF-8"));
        HttpResponse response = httpClient.execute(post,context);

        context.getCookieStore().getCookies().forEach(c -> {
            System.out.println(c.getName() + "=>" + c.getValue());
        });

        //HttpEntity entity = response.getEntity();


        String location = String.valueOf(response.getFirstHeader("Location"));


        return httpClient;
    }

    /**
     * 避免HttpClient的”SSLPeerUnverifiedException: peer not authenticated”异常
     * 不用导入SSL证书
     * @param builder
     * @return
     */
    public static CloseableHttpClient wrapSslClient(HttpClientBuilder builder) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {

                @Override
                public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                        throws java.security.cert.CertificateException {
                    // TODO Auto-generated method stub

                }

                @Override
                public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                        throws java.security.cert.CertificateException {
                    // TODO Auto-generated method stub

                }

                @Override
                public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                    // TODO Auto-generated method stub
                    return null;
                }
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);


            builder.setSSLSocketFactory(ssf);

            CloseableHttpClient httpclient = builder.build();
            return httpclient;
        } catch (Exception ex) {
            ex.printStackTrace();
            return null;
        }
    }


    public static void main(String[] args) throws Exception {
       //kakfa ui
       HttpClient httpClient = casLogin("https://10.22.82.44:20009/cas/login?service=https%3A%2F%2F10.22.82.44%3A20026%2FKafka%2FKafkaUI%2F67%2Fkafka-ui%2Flogin%2Fcas");
       HttpGet httpGet = new HttpGet("https://10.22.82.44:20026/Kafka/KafkaUI/67/kafka-ui/topic/summary/page?pageSize=10&pageNum=0&searchContent=");
       HttpResponse response = httpClient.execute(httpGet);
       String responseString = EntityUtils.toString(response.getEntity());
       System.out.println("Protected Service Response: " + responseString);

       //yarn ui
        HttpClient httpClient_yarn = casLogin("https://10.22.82.44:20009/cas/login");
        //yarn apps
        HttpGet httpGet_yarn = new HttpGet(new URI("https://10.22.82.44:20026/Yarn/ResourceManager/40/ws/v1/cluster/apps?states=RUNNING"));
        httpGet_yarn.setHeader("User-Agent","Mozilla");
        HttpResponse response_yarn = httpClient_yarn.execute(httpGet_yarn);
        String responseString_yarn = EntityUtils.toString(response_yarn.getEntity());
        System.out.println("Protected Service Response: " + responseString_yarn);

        //flink web ui
        HttpGet httpGet_flink_web_ui = new HttpGet("https://10.22.82.44:20026/Yarn/ResourceManager/40/proxy/application_1718331780994_0259/jobmanager/metrics?get=numRunningJobs,taskSlotsTotal");
        httpGet_flink_web_ui.setHeader("User-Agent","Mozilla");
        HttpResponse response_flink_web_ui = httpClient_yarn.execute(httpGet_flink_web_ui);
        String responseString_flink = EntityUtils.toString(response_flink_web_ui.getEntity());
        System.out.println("Protected Service Response: " + responseString_flink);
    }
}
